<tbody #tbody>
  <ng-container *ngIf="cellConfig; else virtualScrollTpl">
    <tr *ngFor="let row of data; index as i; trackBy: trackByItem" [style.gridTemplateColumns]="cellConfig.gridTemplateColumns">
      <td
        *ngFor="let column of cellConfig.cells; index as j"
        [title]="getTitle(row, column)"
        [class.x-table-sticky]="table.getSticky(column)"
        [style.left.px]="column.left"
        [style.grid-area]="column.gridArea"
      >
        <ng-container *ngTemplateOutlet="cellTpl; context: { column: column, row: row, i: i }"></ng-container>
      </td>
    </tr>
  </ng-container>
  <x-empty *ngIf="isEmpty"></x-empty>
</tbody>

<ng-template #virtualScrollTpl>
  <cdk-virtual-scroll-viewport
    #virtualBody
    *ngIf="virtualScroll; else bodyTpl"
    [itemSize]="getItemSize"
    [minBufferPx]="minBufferPx"
    [maxBufferPx]="maxBufferPx"
    [style.height.px]="bodyHeight"
  >
    <tr
      *cdkVirtualFor="let row of data; let index = index; trackBy: trackByItem"
      [class.x-table-activated]="allowSelectRow && activatedRow?.id === row.id"
      [style.height.px]="getRowHeight"
      [style.min-height.px]="getRowHeight"
      (click)="rowClick(row)"
    >
      <!-- rowHeight 为 0 的时候，index 下标获取不到 -->
      <ng-container *ngTemplateOutlet="rowTpl; context: { row: row, i: getIndex(index, row) }"></ng-container>
    </tr>
  </cdk-virtual-scroll-viewport>
</ng-template>

<ng-template #bodyTpl>
  <tr
    *ngFor="let row of data; index as i; trackBy: trackByItem"
    [class.x-table-activated]="allowSelectRow && activatedRow?.id === row.id"
    [style.height.px]="getRowHeight"
    [style.min-height.px]="getRowHeight"
    (click)="rowClick(row)"
  >
    <ng-container *ngTemplateOutlet="rowTpl; context: { row: row, i: i }"></ng-container>
  </tr>
</ng-template>

<ng-template #rowTpl let-row="row" let-i="i">
  <ng-container *ngFor="let column of columns; index as j; trackBy: trackByItem">
    <td
      [style.width.px]="column.width"
      [style.flex]="getFlex(column)"
      [title]="getTitle(row, column)"
      [class.x-table-sticky]="table.getSticky(column)"
      [style.left.px]="column.left"
    >
      <ng-template *ngTemplateOutlet="cellTpl; context: { column: column, row: row, i: i }"></ng-template>
    </td>
  </ng-container>
</ng-template>

<ng-template #cellTpl let-column="column" let-row="row" let-i="i">
  <ng-container [ngSwitch]="column.type">
    <ng-container *ngSwitchCase="'checkbox'">
      <x-checkbox
        [data]="[{ id: true, label: '' }]"
        [(ngModel)]="row[column.id]"
        (ngModelChange)="table.bodyChecked($event, column)"
      ></x-checkbox>
    </ng-container>
    <ng-container *ngSwitchCase="'index'">
      <div>{{ table.getIndex(i) }}</div>
    </ng-container>
    <ng-container *ngSwitchDefault>
      <ng-container *xOutlet="columnTpl[column.id]; context: { $column: column, $row: row, $index: table.getIndex(i) }">
        <div [innerHTML]="row[column.id]" [style.text-align]="column.textAlign"></div>
      </ng-container>
    </ng-container>
  </ng-container>
</ng-template>
